﻿using RQX.Common.Core.Extension;
using RQX.Common.Core.Hardware.BaseCollection;
using RQX.Common.Core.Hardware.Com;
using RQX.Common.Core.Logger;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Maquet_Flow_i
{
    public class Flow_i : AbstractComCollection
    {
        #region 默认配置
        public override int BaudRate => 38400;

        public override int DataBits => 8;

        public override StopBits StopBits => StopBits.One;

        public override Parity Parity => Parity.Even;

        public override bool DTR => false;

        public override bool RTS => false;

        public override DeviceType DeviceType => DeviceType.麻醉机;
        public Flow_i()
        {
        }
        #endregion
        #region 固定值
        private const byte EOT = 0x04;
        private const byte ESC = 0x1B;
        #endregion

        private static bool isCircleSend = false;
        private static string[] BASE_CODE = new string[] { "100", "102", "104", "105", "106", "107", "108", "118", "124" };
        private static string[] SETTING_CODE = new string[] {"411","418" };
        //private static string[] BASE_CODE = new string[] { "110" };//  };
        private static string[] BASE_NAME = new string[] { "RR", "VTe", "MVe", "Ppeak", "Pmean", "Pplat", "PEEP", "FiO2", "EtCO2" };
        private static string[] SETTING_NAME = new string[] { "Fset", "I:E" };
        //private static string[] BASE_NAME = new string[] { "I:E" };//,  };


        public Flow_i(StructureModel<MyCom> structureModel) : base(structureModel)
        {
        }

        protected override Dictionary<string, string> AnalysisData(string msg)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();
            msg = msg.Substring(0, msg.IndexOf("7f"));
            if(msg.Length == 4)
            {
                if (msg.StartsWith("e0"))
                {
                    _lastRecvTime = DateTime.MinValue;
                    return dic;
                }
            }
            else if (msg.Length == 8)//设置的数据
            {
                for(var i = 0; i < SETTING_NAME.Length; i++)
                {
                    if (msg.Length < (i + 1) * 4) break;
                    var valueStr = msg.Substring(i * 4, 4);
                    if (valueStr.Equals("7eff")) continue;
                    double value = 0;
                    try
                    {
                        value = Convert.ToInt32(msg, 16) / 10.0;
                    }
                    catch (Exception ex)
                    {
                        LogUtils.WriteErrorLog($"msg:{ msg}\nex:{ex}");
                    }
                    switch (SETTING_NAME[i])
                    {
                        case "I:E":
                            var ieValue = "";
                            if (value > 1)
                            {
                                ieValue = $"{value}:1";
                            }
                            else
                            {
                                ieValue = $"1:{value}";
                            }
                            dic.Add(SETTING_NAME[i], ieValue);
                            break;
                        default:
                            dic.Add(SETTING_NAME[i], value.ToString());
                            break;
                    }
                }
            }
            else//呼吸的数据
            {
                for (var i = 0; i < BASE_NAME.Length; i++)
                {
                    if (msg.Length < (i + 1) * 4) break;
                    var valueStr = msg.Substring(i * 4, 4);
                    if (valueStr.Equals("7eff")) continue;
                    double value = 0;
                    try
                    {
                        value = Convert.ToInt32(valueStr, 16);
                    }
                    catch (Exception ex)
                    {
                        LogUtils.WriteErrorLog($"msg:{ msg}\nex:{ex}");
                        continue;
                    }
                    switch (BASE_NAME[i])
                    {
                        case "RR":
                        case "FiO2":
                        case "EtCO2":
                        case "Ppeak":
                        case "PEEP":
                        case "Pmean":
                        case "Pplat":
                        value /= 10.0; 
                            break;
                    }
                    dic.Add(BASE_NAME[i], value.ToString());
                }
            }
            return dic;
        }
        protected override StepType CheckRecvMsgType(string lineStr)
        {
            if (lineStr.IsNullOrEmpty() || lineStr.Contains("04"))
            {
                return StepType.None;
            }
            else
            {
                return StepType.DataSource;
            }
        }

        protected override void CircleSend()
        {
            var breathStr = "RADAB";
            var settingStr = "RADAS";
            breathStr = $"{breathStr}{GetCheckNum(breathStr)}{GetEOT()}";
            settingStr = $"{settingStr}{GetCheckNum(settingStr)}{GetEOT()}";
            while (true)
            {
                Thread.Sleep(1000);
                Send(breathStr.ToByte());
                Thread.Sleep(500);
                Send(settingStr.ToByte());
            }
        }

        protected override void Connect(StepType stepNum, string msg)
        {
            var rctyStr = "RCTY";
            rctyStr = $"{rctyStr}{GetCheckNum(rctyStr)}{GetEOT()}";
            Send(rctyStr.ToByte());
            Thread.Sleep(500);
            var breathStr = $"SDADB{string.Join("", BASE_CODE)}";
            breathStr = $"{breathStr}{GetCheckNum(breathStr)}{GetEOT()}";
            Send(breathStr.ToByte());
            Thread.Sleep(500);
            var settingStr = $"SDADS{string.Join("", SETTING_CODE)}";
            settingStr = $"{settingStr}{GetCheckNum(settingStr)}{GetEOT()}";
            Send(settingStr.ToByte());
            if (isCircleSend == false)
            {
                isCircleSend = true;
                Task.Run(() => CircleSend());
            }
        }

        protected override string CutToOneMsg(StringBuilder sb)
        {
            var index = sb.ToString().IndexOf("7f");
            if (index > -1)
            {
                return sb.ToString().Substring(0, Math.Min(index + 4, sb.Length));
            }
            index = sb.ToString().IndexOf("04");
            if (index > -1)
            {
                return sb.ToString().Substring(0, index + 2);
            }
            return "";
        }

        #region 内部函数

        public string GetCheckNum(string dataStr)
        {
            var chk = 0;
            dataStr.ToByte(Encoding.Default).ForEach(ch => chk ^= ch);
            return chk.ToString("X2");
        }
        public string GetEOT() => Encoding.Default.GetString(new byte[] { EOT });
        #endregion
    }
}
